package br.com.felix.dbm.ui;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.IOException;

import javax.swing.JDesktopPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

import br.com.felix.dbm.database.DataModel;
import br.com.felix.dbm.log.Logger;
import br.com.felix.dbm.sql.SQLBuilder;
import br.com.felix.dbm.sql.exception.CannotBuildSQLException;
import br.com.felix.dbm.util.io.FDMFileFilter;
import br.com.felix.dbm.util.io.FDMFileManager;
import br.com.felix.dbm.util.io.SQLFileFilter;
import br.com.felix.dbm.util.io.SQLFileManager;

/**
 * Main Program Window
 * */
public class DatabaseModelerUi extends JFrame {

	private JDesktopPane desktop;
	private ColumnClassCodesUi columnClassCodesUi;

	private static final long serialVersionUID = -3390999249330655417L;

	private Logger logger = Logger.getLogger(DatabaseModelerUi.class);


	public DatabaseModelerUi() {
		super("Database Modeler for Developers - by Carlos Padoa");
		configureDefaults();
		createMenu();
	}



	private void configureDefaults() {
		JFrame.setDefaultLookAndFeelDecorated(true);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setSize(screenSize);
		desktop = new JDesktopPane();
		add(desktop);
		setExtendedState(MAXIMIZED_BOTH);
	}



	private void createMenu() {
		JMenuBar mnuBar = new JMenuBar();
		JMenu mnu = new JMenu("File");
		JMenuItem mniOpen = new JMenuItem("Open");
		JMenuItem mniNew = new JMenuItem("New");
		JMenuItem mniSave = new JMenuItem("Save");
		JMenuItem mniGenerateSQL = new JMenuItem("Generate SQL");
		mnu.add(mniOpen);
		mnu.add(mniNew);
		mnu.add(mniSave);
		mnu.add(mniGenerateSQL);
		mnuBar.add(mnu);

		JMenu mnuWindow = new JMenu("Window");
		JMenuItem mniClassCodes = new JMenuItem("Column Class Codes");
		mnuWindow.add(mniClassCodes);
		mnuBar.add(mnuWindow);

		setJMenuBar(mnuBar);

		mniOpen.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				openFile();
			}
		});

		mniNew.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				createNewFile();
			}
		});

		mniSave.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				saveFile();
			}
		});

		mniGenerateSQL.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				generateSQL();
			}
		});

		mniClassCodes.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				showHideColumnClassCodes();
			}
		});
	}



	protected void showHideColumnClassCodes() {
		if (columnClassCodesUi == null) {
			columnClassCodesUi = new ColumnClassCodesUi();
			columnClassCodesUi.setVisible(true);
		}
		else {
			columnClassCodesUi.dispose();
			columnClassCodesUi = null;
		}

	}



	protected void generateSQL() {
		EditorUi editorUi = (EditorUi) desktop.getSelectedFrame();
		if (editorUi == null)
			return;
		DataModel dm = editorUi.getDataModel();
		SQLBuilder sqlb;
		try {
			sqlb = dm.toSQL();
			logger.debug(sqlb.toString());
			String dataModelName = dm.getName();
			JFileChooser jfc = new JFileChooser();
			String path = jfc.getFileSystemView().getDefaultDirectory() + File.separator + dataModelName + ".sql";
			jfc.setSelectedFile(new File(path));

			jfc.addChoosableFileFilter(new SQLFileFilter());
			jfc.setAcceptAllFileFilterUsed(false);
			int returnVal = jfc.showSaveDialog(getParent());
			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = jfc.getSelectedFile();
				SQLFileManager fdmFileManager = new SQLFileManager();
				try {
					fdmFileManager.save(sqlb, file);
					JOptionPane.showMessageDialog(getParent(), "File saved successfully.");
				}
				catch (IOException e) {
					JOptionPane.showMessageDialog(getParent(), "Could not save file.");
				}
			}

		}
		catch (CannotBuildSQLException e) {
			JOptionPane.showMessageDialog(getParent(), "Could not generate SQL. The following error has ocurred:\n" + e.getMessage(), "Error generating SQL", JOptionPane.ERROR_MESSAGE);
		}
	}



	protected void openFile() {
		JFileChooser jfc = new JFileChooser();
		jfc.addChoosableFileFilter(new FDMFileFilter());
		jfc.setAcceptAllFileFilterUsed(false);
		int returnVal = jfc.showOpenDialog(getParent());
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = jfc.getSelectedFile();
			FDMFileManager fdmFileManager = new FDMFileManager();
			try {
				DataModel dm = fdmFileManager.open(file);
				openEditorForDataModel(dm);
			}
			catch (IOException e) {
				JOptionPane.showMessageDialog(getParent(), "Could not open file.");
			}
		}
	}



	protected void saveFile() {
		EditorUi editorUi = (EditorUi) desktop.getSelectedFrame();
		if (editorUi == null)
			return;
		DataModel dm = editorUi.getDataModel();
		String dataModelName = dm.getName();
		JFileChooser jfc = new JFileChooser();
		String path = jfc.getFileSystemView().getDefaultDirectory() + File.separator + dataModelName + ".fdm";
		jfc.setSelectedFile(new File(path));
		logger.debug(path);

		jfc.addChoosableFileFilter(new FDMFileFilter());
		jfc.setAcceptAllFileFilterUsed(false);
		int returnVal = jfc.showSaveDialog(getParent());
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = jfc.getSelectedFile();
			FDMFileManager fdmFileManager = new FDMFileManager();
			try {
				String projectName = file.getName();
				projectName = projectName.substring(0, projectName.lastIndexOf('.'));
				dm.setName(projectName);
				editorUi.setTitle(projectName);
				fdmFileManager.save(dm, file);
				JOptionPane.showMessageDialog(getParent(), "File saved successfully.");
			}
			catch (IOException e) {
				JOptionPane.showMessageDialog(getParent(), "Could not save file.");
			}
			logger.debug("File",file.getAbsolutePath());
		}

	}



	protected void createNewFile() {
		openEditorForDataModel(new DataModel("New Project"));
	}



	private void openEditorForDataModel(DataModel dm) {
		EditorUi editorUi = new EditorUi(dm);
		desktop.add(editorUi);
		try {
			editorUi.setMaximum(true);
		}
		catch (PropertyVetoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		editorUi.setVisible(true);
	}
}
